package com.cjf.aop.runtime.aspectj;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;

import com.cjf.aop.annotation.ApplyPermission;
import com.cjf.aop.runtime.AOPManager;
import com.cjf.aop.runtime.logger.XLogger;
import com.cjf.aop.runtime.utils.PermissionUtils;
import com.cjf.aop.runtime.utils.Utils;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

import java.util.ArrayList;
import java.util.List;

/**
 * 申请系统权限切片，根据注解值申请所需运行权限
 * created by cjf
 * on: 2020/3/25
 */
@Aspect
public class ApplyPermissionAspectJ {

    /**
     * 带 {@link com.cjf.aop.annotation.ApplyPermission} 注解的类
     */
    @Pointcut("within(@com.cjf.aop.annotation.ApplyPermission *)")
    public void withinAnnotatedClass() {
    }

    @Pointcut("execution(!synthetic * *(..)) && withinAnnotatedClass()")
    public void methodInsideAnnotatedType() {
    }

    //方法切入点，带有@ApplyPermission注解的方法,或者带有@ApplyPermission注解的类并除去synthetic修饰的方法
    @Pointcut("execution(@com.cjf.aop.annotation.ApplyPermission * *(..)) || methodInsideAnnotatedType()")
    public void method() {
    }

    @Around("method() && @annotation(permission)")
    public void aroundJoinPoint(final ProceedingJoinPoint joinPoint, ApplyPermission permission) {
        Object obj = joinPoint.getThis();
        FragmentManager fm = null;
        if (obj instanceof Fragment) {
            fm = ((Fragment) obj).getChildFragmentManager();
        } else if (obj instanceof FragmentActivity) {
            fm = ((FragmentActivity) obj).getSupportFragmentManager();
        }
        new PermissionUtils(fm)
                .permission(permission.value())
                .callback(new PermissionUtils.FullCallback() {
                    @Override
                    public void onGranted(List<String> permissionsGranted) {
                        try {
                            joinPoint.proceed();//获得权限，执行原方法
                        } catch (Throwable e) {
                            e.printStackTrace();
                            XLogger.e(e);
                        }
                    }

                    @Override
                    public void onDenied(List<String> permissionsDeniedForever, List<String> permissionsDenied, List<String> permissionsGranted) {
                        List<String> list = new ArrayList<>();
                        list.addAll(permissionsDenied);
                        list.addAll(permissionsDeniedForever);
                        XLogger.e(Utils.getMethodDescribeMsg(joinPoint)+"权限申请被拒绝:{" + Utils.listToString(list)+"}");
                        if (AOPManager.getInstance().getLocalPermissionDeniedListener().size() > 0) {
                            AOPManager.onLocalPermissionDenied(permissionsDeniedForever, permissionsDenied, permissionsGranted);
                        } else if (AOPManager.getInstance().getOnPermissionDeniedListener() != null) {
                            AOPManager.getInstance().getOnPermissionDeniedListener().onDenied(permissionsDeniedForever, permissionsDenied, permissionsGranted);
                        }
                    }
                })
                .request();
    }
}
